﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace mc_tester
{
    public class Device
    {
        // ebben a tárolóban vannak a portok
        public Dictionary<String, Port> _ports;
        // ebben a tárolóban vannak a parancsok
        public Dictionary<String, byte> _commands;
        
        //max timer száma
        int _activetimer = 0;
        
        // soros portos objektum
        public Communication _comm;

        public Device()
        {
            // feltöltjük a parancsokat
            _commands = new Dictionary<String, byte>();

            _commands.Add("IN", 0x64);
            _commands.Add("OUT", 0x65);
            _commands.Add("LOW", 0x66);
            _commands.Add("HIGH", 0x67);
            _commands.Add("GET", 0x68);
            _commands.Add("ADC", 0x69);
            _commands.Add("TIMERSTART", 0x70);
            _commands.Add("TIMERSTOP", 0x71);

            //létrehozzuk a soros kommunikációs objektumot
            _comm = new Communication(this,Properties.Settings.Default.COMPORT, Properties.Settings.Default.BAUDRATE, Properties.Settings.Default.DATABITS,Properties.Settings.Default.STOPBITS, Properties.Settings.Default.PARITY);

            //feltöltjük a portok tárolóját
            _ports = new Dictionary<String, Port>();
            _ports.Add("INT3", new Port(this, "INT3", 0x21, false));
            _ports.Add("INT2", new Port(this, "INT2", 0x22, false));
            _ports.Add("INT1", new Port(this, "INT1", 0x23, false));
            _ports.Add("INT0", new Port(this, "INT0", 0x24, false));
            _ports.Add("Led3Pin", new Port(this, "Led3Pin", 0x25, false));
            _ports.Add("Led2Pin", new Port(this, "Led2Pin", 0x26, false));
            _ports.Add("Led1Pin", new Port(this, "Led1Pin", 0x27, false));
            _ports.Add("USART1_CLK", new Port(this, "USART1_CLK", 0x28, false));
            _ports.Add("SPI_MOSI", new Port(this, "SPI_MOSI", 0x29, false));
            _ports.Add("SPI_MISO", new Port(this, "SPI_MISO", 0x30, false));
            _ports.Add("SPI_CLK", new Port(this, "SPI_CLK", 0x31, false));
            _ports.Add("USART1_RXD", new Port(this, "USART1_RXD", 0x32, false));
            _ports.Add("USART1_TXD", new Port(this, "USART1_TXD", 0x33, false));
            _ports.Add("I2C_CLK", new Port(this, "I2C_CLK", 0x34, false));
            _ports.Add("I2C_DATA", new Port(this, "I2C_DATA", 0x35, false));
            _ports.Add("UART0_RXD", new Port(this, "UART0_RXD", 0x36, false));
            _ports.Add("UART0_TXD", new Port(this, "UART0_TXD", 0x37, false));
            _ports.Add("PW0", new Port(this, "PW0", 0x38, false));
            _ports.Add("PW2", new Port(this, "PW2", 0x39, false));
            _ports.Add("PW3", new Port(this, "PW3", 0x40, false));
            _ports.Add("PW4", new Port(this, "PW4", 0x41, false));
            _ports.Add("PW5", new Port(this, "PW5", 0x42, false));
            _ports.Add("Adc3", new Port(this, "Adc3", 0x43, true)); //ADC mód
            _ports.Add("Adc2", new Port(this, "Adc2", 0x44, true)); //ADC mód
            _ports.Add("Adc1", new Port(this, "Adc1", 0x45, true)); //ADC mód
            
        }

        public int activetimer
        {
            get
            {
                return _activetimer;
            }
            set
            {
                _activetimer = value ;
            }
        }

        //üzenet küldése sors porton keresztül
        public void sendMessage(string s)
        {
            string[] splitt1 = s.Split(' ');
            

            string s2 = "";
            if (splitt1[0] == Port.COMMANDS.TIMERSTART.ToString())
            {
                // 7E ACK szekvencia forrás(2) cél(2) hossz(1) group(2) AM_TESTERMSG(1) port(1) parancs(1) ido(2) cido(2)
                //itt végezzük a kapott számok byteokat reprezentáló stringgé alakítását.

                byte[] idoBytes = BitConverter.GetBytes(Convert.ToInt32(splitt1[2]));

                if (BitConverter.IsLittleEndian)
                    Array.Reverse(idoBytes);
                byte[] ido = idoBytes;

                byte[] cidoBytes = BitConverter.GetBytes(Convert.ToInt32(splitt1[3]));

                if (BitConverter.IsLittleEndian)
                    Array.Reverse(cidoBytes);
                byte[] cido = cidoBytes;

                s2 = "00 00 FF FF 06 00 00 07 " + Convert.ToInt32(_ports[splitt1[1]].byteValue).ToString("X2") + " " + Convert.ToInt32(_commands[splitt1[0]]).ToString("X2") + " " + ido[2].ToString("X2") + " " + ido[3].ToString("X2") + " " + cido[2].ToString("X2") + " " + cido[3].ToString("X2");
            }
            else
            {
                s2 = "00 00 FF FF 02 00 00 07 " + Convert.ToInt32(_ports[splitt1[1]].byteValue).ToString("X2") + " " + Convert.ToInt32(_commands[splitt1[0]]).ToString("X2");
            }

            
            string[] splitt = s2.Split(' ');


            Escaper buffer = new Escaper(splitt.Length + 6);

            buffer.nextByte(0x44);
            buffer.nextByte(0x10);
            for (int i = 0; i < splitt.Length; i++)
            {
                buffer.nextByte((StringToByteArray(splitt[i]))[0]);
            }

            int crc = buffer.crc;
            buffer.nextByte(crc & 0xff);
            buffer.nextByte(crc >> 8);

            buffer.terminate();

            _comm.sendBytes(buffer.blist());

        }
        public static byte[] StringToByteArray(string hex)
        {
            return Enumerable.Range(0, hex.Length)
                     .Where(x => x % 2 == 0)
                     .Select(x => Convert.ToByte(hex.Substring(x, 2), 16))
                     .ToArray();
        }
    }// end Device class
}
